/**
 * OSS is a Open Service Container which gives the leverage of building the Desktop and Web
 * Application. * Copyright (C) 2008-2009  Ponraj Sutanthiramani
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Or5e Open Source Community
 * 105, S.S Paradise Apartment, Munnireddy Layout, Horamavu, Banaswadi, Bangalore, India.
 */
package org.or5e.api.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.or5e.core.BaseObject;

public class GenericTCPServer extends BaseObject implements TCPServer {
	private static Integer PORT = new Integer(1000);
	private NioSocketAcceptor acceptor = null;
	private Boolean isServerRunning = Boolean.FALSE;
	public final Boolean getIsServerRunning() {
		return isServerRunning;
	}

	private Map<String, List<CmdListener>> cmdListener = null;
	
	@Override
	public void init(String configFile) {
		 acceptor = new NioSocketAcceptor();
		 cmdListener = new HashMap<String, List<CmdListener>>();
		 DefaultIoFilterChainBuilder fChain = acceptor.getFilterChain();
		 fChain.addLast("logger", new LoggingFilter());
		 fChain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
		 acceptor.setHandler(new RequestProcessor(cmdListener));
	}

	@Override
	public void startServer() {
		try {
			info("Server is about to start Listen to the port :"+PORT.intValue());
			acceptor.bind(new InetSocketAddress(PORT.intValue()));
			isServerRunning = Boolean.TRUE;
		} catch (IOException e) {
			e.printStackTrace();
			isServerRunning = Boolean.FALSE;
		}
	}

	@Override
	public void stopServer() {
		acceptor.unbind();
		acceptor.dispose();
	}

	@Override
	public void addCommandListener(String cmd, CmdListener listener) {
		List<CmdListener> listenerList = null;
		info("Setting up a new Listener for a command");
		System.out.println("Adding new Listener :"+cmd);
		synchronized(this.cmdListener) {
			if(this.cmdListener.containsKey(cmd)) {
				listenerList = this.cmdListener.get(cmd);
			}
			else {
				listenerList = new ArrayList<CmdListener>();
				this.cmdListener.put(cmd, listenerList);
			}
			listenerList.add(listener);
		}

	}

	@Override
	public String getName() {
		return "TCP Server";
	}
}
